package part20IO流.hw;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

import part20IO流.Person;

public class 对象流练习_对象序列化追加 {

	public static void main(String[] args) {
		对象流练习_对象序列化追加 t = new 对象流练习_对象序列化追加();
//		t.序列化();
		 t.反序列化();
	}
	/**
	 * Java默认的对象序列化是每次写入对象都会写入一个头部信息aced 0005（占4个字节），
	 * 然后每次读取都读完头然后在读内容。
	 * 解决方法就是先判断文件是否存在。
	 * 如果不存在，就先创建文件。然后写了第一个对象，也写入了头aced 0005。
	 * 追加的情况就是当判断文件存在时，把那个4个字节的头aced 0005截取掉，
	 * 然后在把对象写入到文件。这样就实现了对象序列化的追加。
	 */
	public void 序列化() {
		File file = new File("persons2.txt");
		// 文件输出流
		FileOutputStream fos = null;
		// 对象输出流
		ObjectOutputStream oos = null;

		try {

			List<Person> persons = new ArrayList<Person>();
			persons.add(new Person("UU", "28"));
			persons.add(new Person("UU2", "38"));
			persons.add(new Person("UU3", "48"));
			persons.add(new Person("UU4", "58"));

			boolean isexist = false;// 定义一个用来判断文件是否需要截掉头aced 0005的
			if (file.exists()) { // 文件是否存在

				isexist = true; // 需要裁减
				fos = new FileOutputStream(file, true);
				oos = new ObjectOutputStream(fos);
				long pos = 0;
				if (isexist) {
					pos = fos.getChannel().position() - 4;// 追加的时候去掉头部aced 0005
					fos.getChannel().truncate(pos);
				}
				oos.writeObject(persons);// 进行序列化
				System.out.println("追加成功");

			} else {// 文件不存在

				file.createNewFile();
				fos = new FileOutputStream(file);
				oos = new ObjectOutputStream(fos);
				oos.writeObject(persons);// 进行序列化
				//
				System.out.println("首次对象序列化成功！");
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if (oos != null) {
					oos.close();
				}
				if (fos != null) {
					fos.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	/**
	 * 循环输出反序列化对象
	 * FileInputStream.available()方法判断文件是否还有内容
	 */
	public void 反序列化() {
		File file = new File("persons2.txt");

		FileInputStream fn = null;
		ObjectInputStream ois = null;

		if (file.exists()) {
			try {
				fn = new FileInputStream(file);
				ois = new ObjectInputStream(fn);
				while (fn.available() > 0) {// 代表文件还有内容
					List<Person> list =  (List<Person>) ois.readObject();// 从流中读取对象
					System.out.println(list);
				}
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}finally {
				try {
					if (ois!=null) {
						ois.close();
					}
					if (fn!=null) {
						fn.close();
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}
